package com.ht.web_vr_home_tour_backend.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ht.web_vr_home_tour_backend.config.coustom.BaseUser;
import com.ht.web_vr_home_tour_backend.obj.dto.ResData;
import com.ht.web_vr_home_tour_backend.obj.dto.UserInfoDto;
import com.ht.web_vr_home_tour_backend.obj.enums.UserLevel;
import com.ht.web_vr_home_tour_backend.obj.pojo.UserInfo;
import com.ht.web_vr_home_tour_backend.service.UserInfoService;
import com.ht.web_vr_home_tour_backend.utils.ThreadLocalUtil;
import com.ht.web_vr_home_tour_backend.utils.TokenUtil;
import com.ht.web_vr_home_tour_backend.utils.UserPwdUtil;
import com.ht.web_vr_home_tour_backend.utils.exceptions.ControllerParamException;
import com.ht.web_vr_home_tour_backend.utils.exceptions.MessageException;
import com.ht.web_vr_home_tour_backend.utils.exceptions.ServiceDataNullException;
import com.ht.web_vr_home_tour_backend.utils.interfaces.RequiredUserLevel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/api/user")
@Api(tags="用户数据控制器")
@Slf4j
public class UserInfoController {
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private BaseUser baseUser;

    @ApiOperation("用户登录")
    @PostMapping("/login")
    @RequiredUserLevel(UserLevel.Tourists)
    public ResData<String> login(@RequestBody UserInfo userInfo, HttpServletResponse response) {
        String token = userInfoService.login(userInfo.getUsername(), userInfo.getPassword());
        if (token == null) {
            return ResData.fail("用户名或密码错误");
        } else {
            return ResData.success(null, token);
        }
    }

    @ApiOperation("创建用户")
    @PostMapping("/create")
    @RequiredUserLevel(UserLevel.Tourists)
    public ResData<Void> createUser(@RequestBody UserInfo userInfo) {
        try {
            userInfoService.createUser(userInfo);
        } catch (ServiceDataNullException e) {
            throw new MessageException("创建用户失败，请检查输入参数");
        }
        return ResData.success();
    }

    @ApiOperation("查看用户是否存在")
    @GetMapping("/exists/{username}")
    @RequiredUserLevel(UserLevel.Tourists)
    public ResData<Boolean> userExists(@PathVariable String username) {
        boolean exists = userInfoService.exists(userInfoService.lambdaQuery().eq(UserInfo::getUsername, username));
        return ResData.success(exists);
    }

    @ApiOperation("获取用户")
    @GetMapping("/{userId}")
    @RequiredUserLevel(UserLevel.User)
    public ResData<UserInfoDto> getUser(@PathVariable String userId) {
        if (StrUtil.isBlankIfStr(userId)) {
            throw new MessageException("参数为空");
        }
        UserInfo userById = userInfoService.getUserById(userId);
        if (userById == null) {
            throw new MessageException("用户不存在");
        }
        return ResData.success(new UserInfoDto(userById));
    }

    @ApiOperation("分页获取用户数据")
    @GetMapping("/page")
    @RequiredUserLevel(UserLevel.Admin)
    public ResData<IPage<UserInfoDto>> pageUser(@RequestParam(value = "current", defaultValue = "1") Long current,
                                                @RequestParam(value = "size", defaultValue = "10") Long size) {
        return ResData.success(userInfoService.pageUser(current, size));
    }

    @ApiOperation("更新用户信息，普通用户只能更新自己的信息，管理员能够更新所有用户，不能更新用户密码")
    @PostMapping
    @RequiredUserLevel(UserLevel.User)
    public ResData<String> updateUser(@RequestBody UserInfoDto userInfoDto, HttpServletResponse response) {
        if (userInfoDto.getId() != null) {
            throw new ControllerParamException();
        }
        UserInfoDto localUserInfoDto = ThreadLocalUtil.getUserInfoDto();
        if (localUserInfoDto.getLevel().getVal() >= UserLevel.Admin.getVal() ||
                localUserInfoDto.getId().equals(userInfoDto.getId())
        ) {
            UserInfo newUserInfo = userInfoService.updateUser(new UserInfo(userInfoDto));
            return ResData.success(null, TokenUtil.createToken(new UserInfoDto(newUserInfo)));
        }
        throw new MessageException("权限不足，无法操作");
    }

    @ApiOperation("修改用户密码")
    @PostMapping("/pwd")
    @RequiredUserLevel(UserLevel.User)
    public ResData<String> updatePassword(@RequestBody String newPassword, HttpServletResponse response) {
        if (StrUtil.isBlank(newPassword)) {
            throw new ControllerParamException();
        }
        UserInfoDto userInfoDto = ThreadLocalUtil.getUserInfoDto();
        UserInfo userInfo = new UserInfo(userInfoDto);
        userInfo.setPassword(UserPwdUtil.encode(newPassword));
        UserInfo newUserInfo = userInfoService.updateUser(userInfo);
        return ResData.success(null, TokenUtil.createToken(new UserInfoDto(newUserInfo)));
    }

    @ApiOperation("获得基础用户")
    @GetMapping("/basic")
    @RequiredUserLevel(UserLevel.Tourists)
    public ResData<UserInfoDto> getBasicUser() {
        return ResData.success(baseUser);
    }
}
